﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace AnOtherBlog.Core
{
	/// <summary>
	/// Categorías en las que se organizan las publicaciones
	/// </summary>
	public class Category : BlogBaseClass<Category, Guid>, IComparable<Category>
	{

		#region Constructor

		/// <summary>
		/// Constructor por defecto
		/// </summary>
		public Category()
		{
			base.Id = Guid.NewGuid();
		}

		/// <summary>
		/// Constructor automatizado
		/// </summary>
		/// <param name="cateoryName">Nombre o Titulo de la categoría</param>
		/// <param name="description">Descripción de la categoría</param>
		public Category(Guid categoryID, string categoryName, string description)
		{
			this.Id = categoryID;
			this.CategoryName = categoryName;
			this.Description = description;
		}

		/// <summary>
		/// Constructor automatizado
		/// </summary>
		/// <param name="cateoryName">Nombre o Titulo de la categoría</param>
		/// <param name="description">Descripción de la categoría</param>
		public Category(string categoryName, string description)
		{
			this.Id = Guid.NewGuid();
			this.CategoryName = categoryName;
			this.Description = description;
		}

		#endregion

		#region Fields and Properties

		/// <summary>
		/// Identificador único de la categoría
		/// Id de la clase base
		/// </summary>
		public Guid CategoryID
		{
			get
			{
				return this.Id;
			}
			set
			{
				this.Id = value;
			}
		}

		private string _CategoryName;
		/// <summary>
		/// Nombre de la categoría
		/// </summary>
		public string CategoryName
		{
			get
			{
				return _CategoryName;
			}
			set
			{
				_CategoryName = value ?? string.Empty;
			}
		}

		private string _Description;
		/// <summary>
		/// Descripción de la categoría
		/// </summary>
		public string Description
		{
			get
			{
				return _Description;
			}
			set
			{
				_Description = value ?? string.Empty;
			}
		}

		private int _BlogID;
		/// <summary>
		/// Identificador único del blog (en esta base de datos)
		/// </summary>
		public int BlogID
		{
			get
			{
				return _BlogID;
			}
			set
			{
				_BlogID = value;
			}
		}

		#endregion

		#region Fields and Properties NOT Serialized
		//public static List<Category> categories
		//{
		//  get
		//  {
		//    return Providers.DataAccess.CategoryList();
		//  }
		//}

		#endregion


		#region Persist Methods

		/// <summary>
		/// Obtiene una categoría de acuerdo a su id.
		/// </summary>
		/// <param name="id">Identificador de la categoría </param>
		/// <returns>Objeto categoria</returns>
		public static Category Load(Guid id)
		{
			return Providers.DataAccess.CategorySelect(id);
		}

		/// <summary>
		/// Obtiene una colección con todas las categorías
		/// </summary>
		/// <returns>Colección con todas las categorías del blog</returns>
		public static List<Category> LoadAll()
		{
			return Providers.DataAccess.CategoryList();
		}

		/// <summary>
		/// Almacena la categoría
		/// </summary>
		public void Save()
		{
			//this.DateModified = DateTime.Now;
			if (this.IsNew)
			{
				if (Blog.Current.CategoryExists(this.CategoryName))
				{
					throw new	Exception("Ya existe una categoría con el nombre: " + this.CategoryName);
				}

				Providers.DataAccess.CategoryInsert(this);
				Blog.Current.Categories.Add(this);
			}
			else
			{
				Providers.DataAccess.CategoryUpdate(this);
				// TODO: Que pasa si cambia el nombre de la categoría ?
			}
		}

		#endregion








		#region IComparable<Category> Members

		/// <summary>
		/// Compares the current object with another object of the same type.
		/// </summary>
		/// <param name="other">An object to compare with this object.</param>
		/// <returns>
		/// A 32-bit signed integer that indicates the relative order of the objects being compared. 
		/// The return value has the following meanings: Value Meaning Less than zero This object is 
		/// less than the other parameter.Zero This object is equal to other. Greater than zero This object is greater than other.
		/// </returns>
		/// <remarks>
		/// Compara los títulos de las categorías ignorando mayúsculas y minúsculas
		/// </remarks>
		public int CompareTo(Category other)
		{
			return string.Compare(this.CategoryName, other.CategoryName, true);
		}

		#endregion
	}
}
